package com.ericsson.middleware.PermanentPooling;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import com.ericsson.middleware.PropertiesProvider;
import com.ericsson.middleware.ContextBroker.ContextBrokerClient;
import com.ericsson.middleware.ContextBroker.UpdateContext;
import com.ericsson.middleware.ContextBroker.UpdateContextResponse;
import com.ericsson.middleware.dao.ParkingSpotDao;
import com.ericsson.middleware.entities.ParkingSpotState;
import com.ericsson.middleware.slsp.ParkingSpot;
import com.ericsson.middleware.slsp.SmartParkingClient;
import com.ericsson.middleware.utils.JsonUtil;
import com.ericsson.middleware.utils.StringNormalizer;

@Component
public class ParkingSpotsAsyncWorker implements ParkingSpotsWorker {

	private final static Logger LOGGER = Logger
			.getLogger(ParkingSpotsAsyncWorker.class.getName());
	
	private String updateAction = PropertiesProvider.getUPDATE_ACTION_UPDATE();
	
	@Async
	public void work(int i) {

		LOGGER.log(Level.INFO, "Parking Spot Poller...");

		// polling GET/Parking Spots
		SmartParkingClient parkingSpotClient = new SmartParkingClient();
		ParkingSpot[] parkingSpots = parkingSpotClient.getParkingSpots();

		// check all lamps state
		for (ParkingSpot temp : parkingSpots) {
			ParkingSpotDao parkingSpotService = new ParkingSpotDao();
			String builtId = StringNormalizer.normalize(temp.getStreetAddress() + "_"
					+ temp.getAddress());

			ParkingSpotState fromDB = null;
			try {
				fromDB = parkingSpotService.findById(builtId);
			} catch (Exception e) {
				LOGGER.log(Level.SEVERE, "failed to find " + builtId + " : " + e.getMessage());
				fromDB = null;
			}			

			if (fromDB == null || !fromDB.getStatus().equals(temp.getStatus())) {

				LOGGER.log(
						Level.INFO, "Will update " + builtId);

				ParkingSpotState updateParkingSpot = new ParkingSpotState(StringNormalizer.normalize(temp.getStreetAddress() + "_"
						+ temp.getAddress()), temp.getStatus(),
						temp.getLat(), temp.getLng());
				
				// if there is no entry on database, insert. 
				try {
					if (fromDB == null) {
						parkingSpotService.insert(updateParkingSpot);
						updateAction = PropertiesProvider.getUPDATE_ACTION_APPEND();
					}
					else {
						parkingSpotService.update(updateParkingSpot);
						updateAction = PropertiesProvider.getUPDATE_ACTION_UPDATE();
					}
				} catch (Exception e) {
					LOGGER.log(Level.SEVERE, "failed to update database" + updateParkingSpot.getId());
					updateAction = "UPDATE";
				}

				try {
					ContextBrokerClient cbClient = new ContextBrokerClient();
					UpdateContext updateContext = cbClient.buildUpdateContext(PropertiesProvider.getPARKING_SPOTS_TYPE(), updateAction, temp);
					LOGGER.log(Level.INFO, "Update request: " + JsonUtil.toJson(updateContext));
					UpdateContextResponse response = cbClient.sendUpdateContextWithReAttempts(JsonUtil.toJson(updateContext), Integer.parseInt(PropertiesProvider.getUPDATE_REATTEMPTS()));
					LOGGER.log(Level.INFO, "Update response: " + JsonUtil.toJson(response));					

				} catch (Exception e) {
					LOGGER.log(Level.SEVERE, "failed to update Context Broker" + updateParkingSpot.getId());
				}

			}
		}

	}
}